package helper

import (
	"github.com/yl10/kit/orm"
)

// Context 上下文
// 只限制在每次 Request 内
type Context struct {
	db      *orm.XormPlus
	options map[string]interface{}
	User    interface{}
	Box     map[string]interface{}
}

// NewContext 初始化上下文
func NewContext(db *orm.XormPlus, opt map[string]interface{}) *Context {
	return &Context{
		db:      db,
		options: opt,
		Box:     make(map[string]interface{}),
	}
}

// Ready Request 级别初始化
func (c *Context) Ready(options map[string]interface{}) error {
	if options != nil {
		c.options = options
	}

	// 自动提交, 默认是否
	autoCommit, _ := c.getOption("autoCommit", false).(bool)
	if !autoCommit {
		// 开启事务
		if err := c.openDBTransaction(); err != nil {
			return err
		}
	}

	return nil
}

// Destroy 析构函数
func (c *Context) Destroy() {
	// 自动提交, 默认是否
	autoCommit, _ := c.getOption("autoCommit", false).(bool)
	if !autoCommit {
		c.closeDBTransaction()
	} else {
		c.db.Close()
	}
}

// Commit 提交
func (c *Context) Commit() error {
	return c.db.Commit()
}

// RollBack 回滚
func (c *Context) RollBack() error {
	return c.db.Rollback()
}

// GetDB 获取数据库操作实例
func (c *Context) GetDB() *orm.XormPlus {
	return c.db
}

// SetDB 设置数据库操作实例
func (c *Context) SetDB(db *orm.XormPlus) *Context {
	c.db = db
	return c
}

// openDBTransaction 开启事务
func (c *Context) openDBTransaction() error {
	// 开启写事务
	if err := c.db.Begin(); err != nil {
		return err
	}

	return nil
}

// closeDBTransaction 关闭事务
// 注意, 事务关闭后, DB 将不能再使用
func (c *Context) closeDBTransaction() error {
	// 自动提交, 默认是否
	autoCommit, _ := c.getOption("autoCommit", false).(bool)

	if !autoCommit {
		c.db.Close()
	}

	return nil
}

// getOption 读取配置项
func (c *Context) getOption(key string, def interface{}) interface{} {
	if c.options != nil {
		if opt, has := c.options[key]; has {
			return opt
		}
	}

	return def
}
